package com.smartmail.mime;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;

import javax.mail.FetchProfile;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.UIDFolder;
import javax.mail.internet.MimeMessage;

import android.os.Environment;
import android.util.Log;

import com.smartmail.Attachment;
import com.smartmail.accounts.MailAccount;
import com.smartmail.mailing.MailMessage;
import com.smartmail.utility.MessageUtility;

/**
 * 
 * @author Tomek
 * 
 *         That class has some useful methods to parse mime messages
 * 
 */
public class MimeParser {


	/**
	 * log tag for logging purposes
	 */
	private static String _logTag = "com.smartmail.mime";
	
	public static void getAllAttachments(Part p, List<Attachment> attachments){
		
		try{
			String disposition = p.getDisposition();
			
			if( p.isMimeType("multipart/*")){
				
				Multipart mp = (Multipart) p.getContent();
				//iterate all parts of multipart
				for (int i = 0; i < mp.getCount(); i++)
					getAllAttachments(mp.getBodyPart(i), attachments);	
			}
			else if( (disposition != null)  && p.getFileName() != null &&
					 (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))){
			
				String attachName = decode(p.getFileName());
				Attachment attachment = new Attachment(attachName,null, 0, "");
				
				attachment.setPart(p);
				attachments.add(attachment);
			}
		} catch(MessagingException e){
			
			Log.d(_logTag, "MimeParser : getAllAtachments");
			Log.d(_logTag, "MimeParser : " + e.getMessage() + " " + e.toString());
			
		} catch(IOException e){
			
			Log.d(_logTag, "MimeParser : getAllAtachments");
			Log.d(_logTag, "MimeParser : " + e.getMessage() + " " + e.toString());
		}
	}


	public static String decode(String name) throws UnsupportedEncodingException {

		if (name == null || name.length() == 0) {
			return "unknown";
		}
		String ret = java.net.URLDecoder.decode(name, "UTF-8");

		// also check for a few other things in the string:
		ret = ret.replaceAll("=\\?utf-8\\?q\\?", "");
		ret = ret.replaceAll("\\?=", "");
		ret = ret.replaceAll("=20", " ");

		return ret;
	}

	/******************************************************************************/

	/**
	 * Return the primary text content of the message.
	 */
	public static String getText(Part p) throws MessagingException, IOException {


		//if message is simply text
		if (p.isMimeType("text/*")) {
			
			String s = null;
			try{
				s = (String) p.getContent();
			} catch(IOException e){
				
				s = "BASE64Decoder error. Received Message is broken";
			}
			return s;
		}

		//if message is composed of few alternatives
		if (p.isMimeType("multipart/alternative")) {
			
			// prefer html text over plain text
			Multipart mp = (Multipart) p.getContent();
			String text = null;
			
			//iterate all parts of multipart
			for (int i = 0; i < mp.getCount(); i++) {
				
				Part bp = mp.getBodyPart(i);
				
				if (bp.isMimeType("text/plain")) {
					if (text == null)
						text = getText(bp);
					continue;
				} 
				else if (bp.isMimeType("text/html")) {
					String s = getText(bp);
					if (s != null)
						return s;
				} 
				else
					return getText(bp);	
			}
			
			return text;
		} 
		//if message is other type of multipart
		else if (p.isMimeType("multipart/*")) {
			
			Multipart mp = (Multipart) p.getContent();
			
			//iterate all parts of multipart
			for (int i = 0; i < mp.getCount(); i++) {
				
				String s = getText(mp.getBodyPart(i));
				if (s != null)
					return s;
			}
		}

		return null;
	}

	

	

	
}
